home *** CD-ROM | disk | FTP | other *** search
- #include "pwrglove.h"
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/memory.h>
- #include <exec/interrupts.h>
- #include <hardware/cia.h>
- #include <resources/cia.h>
-
- #include <proto/exec.h>
-
- static volatile int times_up;
- extern struct CIA ciab;
- static struct Library *CIAResource;
- static struct Interrupt interrupt;
- static UBYTE interrupting;
-
- void closetimer(void);
-
- void
- fatal(char *s)
- {
- printf("fatal error: %s\n", s);
- closetimer();
- exit(1);
- }
-
- void
- timerhandler()
- {
- /* hardware timer interrupt */
- times_up = 1;
- }
-
- void
- timersleep(long ticks)
- {
- times_up = 0;
-
- ticks -= 8; if (ticks <= 0) { times_up=1; return; } /* yucko */
-
- /* 1.397 usec * n */
- ciab.ciatblo = ticks & 0xff;
- ciab.ciatbhi = (ticks>>8) & 0xff;
-
- /* one-shot */
- ciab.ciacrb |= CIACRBF_RUNMODE | CIACRBF_LOAD | CIACRBF_START;
-
- while (!times_up) {}
- }
-
- void
- opentimer()
- {
- static char* timername = "glove.timer";
-
- /* install interrupt handler */
- CIAResource = OpenResource(CIABNAME);
- if (CIAResource == NULL) fatal("can't get timer resource");
-
- interrupt.is_Node.ln_Type = NT_INTERRUPT;
- interrupt.is_Node.ln_Pri = 127;
- interrupt.is_Node.ln_Name = timername;
- interrupt.is_Data = NULL;
- interrupt.is_Code = timerhandler;
- if (AddICRVector(CIAResource, CIAICRB_TB, &interrupt) != NULL) {
- fatal("can't use CIA B Timer B");
- }
-
- /* this timer is all mine */
- interrupting = 1;
-
- SetICR(CIAResource, CIAICRF_TB);
- AbleICR(CIAResource, CIAICRF_SETCLR | CIAICRF_TB);
- times_up = 0;
- }
-
- void
- closetimer()
- {
- if (interrupting) {
- ciab.ciacrb &= ~CIACRBF_START;
- AbleICR(CIAResource, CIAICRF_TB);
- RemICRVector(CIAResource, CIAICRB_TB, &interrupt);
- interrupting = 0;
- }
- }
-
- extern struct CIA far ciaa;
-
- /* bits from parallel port -- Alan's hack */
- #define GDATA 0x04 /* glove data in */
- #define GLATCH 0x02 /* glove latch out */
- #define GCLOCK 0x01 /* glove clock out */
- #define GCLOLAT (GLATCH|GCLOCK) /* latch and clock */
-
- #define getbit() (ciaa.ciaprb & GDATA) >> 2
- #define initport() ciaa.ciaddrb = GCLOLAT
-
- /* delays in microseconds */
- #define D2BYTES 96
- #define D2BITS 22
- #define D2SLOW 14720
-
- #define C0L0() ciaa.ciaprb = 0 /* clock 0 latch 0 */
- #define C0L1() ciaa.ciaprb = GLATCH /* clock 0 latch 1 */
- #define C1L0() ciaa.ciaprb = GCLOCK /* clock 1 latch 0 */
- #define C1L1() ciaa.ciaprb = GCLOLAT /* clock 1 latch 1 */
-
- #define setporta() delay(3)
- #define setportb() delay(3)
-
- unsigned char getbyte (void);
-
- /* convert microseconds to cia ticks */
- #define delay(usec) timersleep((usec*1397)/1000)
-
- int control_c()
- {
- closetimer();
- printf("<<goodbye>>\n");
- return 1; /* causes exit */
- }
-
- void query_glove(glove_data *g)
- {
- unsigned char buf[12];
- register char *bp;
-
- /* read 12 byte packet */
- bp = buf;
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2BYTES);
- *bp++ = getbyte ();
- delay (D2SLOW);
- *bp++ = getbyte ();
- delay (D2SLOW);
- *bp++ = getbyte ();
- delay (D2SLOW);
- *bp++ = getbyte ();
- delay (D2SLOW);
- *bp++ = getbyte ();
- delay (D2SLOW);
-
- /* Glove packet isn't quite as described above */
- /* Let's see if we can figure it out */
- {
- int i,k,n;
-
- /* look for FF FF A0 */
- /* almost always starts at offset 7 so look there first */
- n = -1;
- for (k=0,i=7; k<12; ++k,++i) {
- if (buf[i%12] == (unsigned char)0xff &&
- buf[(i+1)%12] == (unsigned char)0xff &&
- buf[(i+2)%12] == (unsigned char)0xa0) {
-
- /* yah! */
- n = (i+3)%12;
- g->x = buf[n];
- g->y = buf[(n+1)%12];
- g->z = buf[(n+2)%12];
- g->rot = buf[(n+3)%12];
- g->fingers = buf[(n+4)%12];
- g->keys = buf[(n+5)%12];
- g->dum0 = 0xa0;
- g->dum7 = buf[(n+6)%12];
- g->dum8 = buf[(n+7)%12];
- g->dum9 = buf[(n+8)%12];
- g->dumA = 0xff;
- g->dumB = 0xff;
- return;
- }
- }
- /* no valid data found */
- }
- }
-
- unsigned char getbyte ()
- {
- register unsigned Glov = 0;
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a reset (latch) pulse */
- C1L0 ();
- C1L1 ();
- delay(5); /* 5 us delay */
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- return (unsigned char) Glov; /* return the byte */
- }
-
-
- void init_glove()
- {
- register unsigned char Glov = 0;
-
- opentimer();
- onbreak(control_c);
-
- /* initialize hardware interface */
- initport();
-
- /* read 4 bits from glove */
- setportb ();
-
- /* generate a reset (latch) pulse */
- C1L0 ();
- C1L1 ();
- delay(5); /* 5 us delay */
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* configure port a as input */
- setporta ();
-
- /* read a bit */
- Glov <<= 1;
- Glov |= getbit();
-
- /* prepare port b as output port */
- setportb ();
-
- /* generate a clock pulse */
- C0L0 ();
- C1L0 ();
-
- /* end of read 4 bits */
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 ();
- delay(7212);
- /* delay (16950); /* 7212 us delay */
-
- setportb ();
-
- C1L1 ();
- delay(2260);
- /* delay (4750); /* 2260 us delay */
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 (); /* Start of 1. Byte */
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 ();
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 ();
- C0L0 ();
- C1L0 ();
- delay (D2BYTES);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 (); /* Start of 2. Byte */
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 ();
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 ();
- C0L1 ();
- C1L1 ();
- delay (D2BYTES);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 (); /* Start of 3. Byte */
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 ();
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 ();
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BYTES);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 (); /* start of 4. byte */
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BYTES);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 (); /* start of 5. byte */
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 ();
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 ();
- C0L0 ();
- C1L0 ();
- delay (D2BYTES);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 (); /* start of 6. byte */
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L1 ();
- C1L1 ();
- delay (D2BYTES);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 (); /* start of 7. byte */
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C0L0 ();
- C1L0 ();
- delay (D2BITS);
-
- /* prepare port b as output port */
- setportb ();
-
- C1L1 ();
- C0L1 ();
- C1L1 ();
- delay(892);
- /* delay (1090); /* 892 us delay (end of 7. byte) */
-
- /* prepare port b as output port */
- setportb ();
-
- C1L0 ();
- delay(50000);
- /* delay (60000); /* some time for the glove controller
- to relax */
- }
-